Skip to content

Fix atomic ordering#8384

Open
tlively wants to merge 2 commits intomainfrom
atomic-effects
Open

Fix atomic ordering#8384
tlively wants to merge 2 commits intomainfrom
atomic-effects

Conversation

@tlively
Copy link
Member

@tlively tlively commented Feb 25, 2026

EffectAnalyzer previously considered atomic operations to be ordered
only with operations that read or write Wasm memories. But they should
be ordered with all operations that read or write the machine's memory,
which includes things like globals, tables, and the GC heap. Fix the problem.

To avoid regressions on MVP programs that want to be able to freely reorder instructions like global.get and memory.grow (which is atomic, preventing such reordering), update the effects of all atomic instructions to be atomic only when operating on shared memory, including shared heap types. This is valid because the ordering of atomic operations on unshared locations can never synchronize with or be observed by operations on other threads.

EffectAnalyzer previously considered atomic operations to be ordered
only with operations that read or write Wasm memories. But they should
be ordered with all operations that read or write the machine's memory,
which includes things like globals, tables, and the GC heap. Fix the
problem. One test is updated now that memory.grow (which is atomic) is
ordered with global accesses.
@tlively tlively enabled auto-merge (squash) February 25, 2026 21:38
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this regressed for a good reason, though it's hard to tell - please add a targeted test for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the best way to test effects.h? Is there an optimization that tries to reorder things in an especially predictable way?

Copy link
Member

@kripken kripken Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SimplifyLocals might be easiest. It does

(local.set $x (..value..))
(..effect..)
(local.get $x)

=>

;; local.set removed
(..effect..)
(..value..) ;; get replaced, value moved past effect, if that was valid

;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
(func $~lib/allocator/arena/__memory_allocate (; 6 ;) (type $3) (param $0 i32) (result i32)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually why did this regress? I don't see an atomic operation here...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the memory.grow, as mentioned in the commit message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, is memory.grow atomic even when atomics are disabled? That is the case in the test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and that seems harmful for optimization of MVP code)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it currently is. I agree we should fix that.

@tlively tlively disabled auto-merge February 25, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants